<?php

namespace IDock\Insurance\LIHI\Response;

use IDock\Http\Response;
use IDock\IDock\IDockEnums;
use IDock\Insurance\LIHI\LIHIEnums;
use IDock\Printer\NonCar\NonCarInquiryPrinter;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Printer\Premium\PremiumBIPrinter;
use IDock\Printer\Premium\PremiumCoveragePrinter;
use IDock\Printer\Premium\PremiumInquiryPrinter;
use IDock\Printer\SpecialClausesPrinter;
use IDock\Printer\VehiclePrinter;
use IDock\Visitor\Premium\PremiumInquiryVisitor;

class PremiumInquiryResponse extends AllLIHIResponse
{

    /**
     * @var PremiumInquiryVisitor $visitor
     */
    public $visitor;

    private $status;

    private $resultCode;

    private $resultMessage;

    public function resolve(): Response
    {
        $body = $this->getBody();

        if (!json_decode($body)) {
            $this->setError('返回数据异常');
            return $this;
        }
        $data = json_decode($body, true);

        $state = $data['state'] ?? '';

        $result = $data['result'] ?? '';

        if ($state == 1 and is_string($result)) {
            $this->setError($data['result'] ?? '');
            return $this;
        }

        if ($this->printer and is_string($this->printer)) {
            $this->printer = new $this->printer;
        }

        $this->resultCode = $data['result']['resultCode'] ?? '';

        $this->resultMessage = trim($data['result']['resultMessage'] ?? '');

        $this->status = $data['result']['status'] ?? '';

        $this->setBody($data);

        return $this;
    }

    /**
     * @var PremiumInquiryPrinter $printer
     * @var  $printer
     */
    public $printer = PremiumInquiryPrinter::class;

    protected $records = [];

    protected $result = [];

    public $planCode = '';

    public $productCode = '';

    public $insuredNum = 1;

    public $renewalFlag;

    public function printerInit(): Response
    {
        if (!$this->printer->success) {
            return $this;
        }
        $body = $this->getBody()['result'] ?? [];

        $mainData = $body['tprpTmainDto'] ?? [];
        $biStartDate = $mainData['startDate'] ?? '';
        $ciStartDate = $mainData['mtplStartDate'] ?? '';

        //询价不成功
        if (!$this->status) {
            $biStartDate = $biStartDate ?: $this->visitor->biStartData;
            $ciStartDate = $ciStartDate ?: $this->visitor->ciStartData;
            //重复投保判定
            $this->repeat($body, $biStartDate, $ciStartDate);

            if ($this->printer->repeatInsuredFlg) {
                $this->printer->repeatMessage = $this->resultMessage;
                $this->printer->success = false;
            } else {
                $this->setError($this->resultMessage);
            }
            return $this;
        }
        $this->printer->argc['flowId'] = $body['flowId'] ?? '';

        $subPremium = $body['subPremium'] ?? '';

        //询价成功 非强校验
        if ($this->resultCode == '0001') {
            //询价车型
            if ($this->vehicleModelList($body['vehicleDtos'] ?? [])) {
                $this->printer->success = false;
                return $this;
            }

            //重复投保判定
            $this->printer->repeatMessage = $this->resultMessage;

            $re = $this->repeat2($body, $biStartDate, $ciStartDate);

            if (!$subPremium) {
                $this->printer->success = false;
                return $this;
            }

            if ($re and $this->visitor->repeatFlag) {
                $this->printer->success = false;
                return $this;
            }
        }

        if (!$subPremium) {
            //询价车型
            if ($this->vehicleModelList($body['vehicleDtos'] ?? [])) {
                $this->printer->success = false;
                return $this;
            }
        }

        if (!$subPremium) {
            throw new \Exception('保行通提示：保费为空，车型为空，自动续接失败，数据异常');
        }

        //车船税
        if ($carShipTax = $body['prpTcarshipTaxDto'] ?? '') {
            $this->printer->carTaxPrinter->carShipTax = $carShipTax['sumTax'] ?? '';
            $this->printer->carTaxPrinter->overdue = $carShipTax['dealyPayPenylty'] ?? '';
            $this->printer->carTaxPrinter->thisYearTax = $carShipTax['vehicleTax'] ?? '';
        }

        $riskArr = $body['tprpTitemKindListDto'] ?? [];
        $biBasePremium = $biPremium = 0;
        foreach ($riskArr as $value) {
            if ($value['kindCodeMain'] == 'BZ') {
                //交强险
                $this->printer->ciPremiumPrinter->ciPremium = $value['premiumMain'] ?? '';
                $this->printer->ciPremiumPrinter->ciBasePremium = $value['benchMarkPremiumMain'] ?? '';
                $this->printer->ciPremiumPrinter->ciDiscount = $value['mtplDiscountMain'] ?? '';
                $startDate = $mainData['mtplStartDate'] ?? '';
                $this->printer->ciPremiumPrinter->ciStartData = mktime($mainData['mtplStartHour'] ?? '0', '0', '0', date('m', strtotime($startDate)), date('d', strtotime($startDate)), date('Y', strtotime($startDate)));
                $this->printer->ciPremiumPrinter->ciStartData = date('Y-m-d H:i:s', $this->printer->ciPremiumPrinter->ciStartData);
                $endDate = $mainData['mtplEndDate'] ?? '';
                $this->printer->ciPremiumPrinter->ciEndData = mktime($mainData['mtplEndHour'] ?? '', '0', '0', date('m', strtotime($endDate)), date('d', strtotime($endDate)), date('Y', strtotime($endDate)));
                $this->printer->ciPremiumPrinter->ciEndData = date('Y-m-d H:i:s', $this->printer->ciPremiumPrinter->ciEndData);
                $this->printer->ciInquiryNo = $mainData['mtplProposalNo'] ?? '';
                $ciFactor = $body['mtplPlatDto'] ?? [];

                $this->printer->premiumFactorPrinter->TCIFactorAppend('交强险系数', 'rpaCause', $ciFactor['rpaCause'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('理赔调整系数', 'claimAdjustReasonValue', $ciFactor['claimAdjustReasonValue'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('理赔浮动原因', 'claimAdjustReason', $ciFactor['claimAdjustReason'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('违法浮动原因代码', 'peccancyAdjustReason', $ciFactor['peccancyAdjustReason'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('违法调整系数', 'peccancyAdjustReasonValue', $ciFactor['peccancyAdjustReasonValue'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('不浮动原因', 'rateFloatFlag', $ciFactor['rateFloatFlag'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('业务评分', 'pointNumber', $ciFactor['pointNumber'] ?? '');
                $this->printer->premiumFactorPrinter->TCIFactorAppend('分值等级', 'pointGrade', $ciFactor['pointGrade'] ?? '');

                if ($ciFactor['lastEndDate'] ?? '') {
                    $this->printer->premiumFactorPrinter->TCIFactorAppend('上年交强险终保日期', 'lastCiEndData', $ciFactor['lastEndDate'] ?? '');
                    $this->printer->premiumFactorPrinter->TCIFactorAppend('上年交强险起保日期', 'lastCiStartData', $ciFactor['lastStartDate'] ?? '');
                }

            } else {
                //商业险
                $biPremium += $value['premiumMain'] ?? 0;
                $biBasePremium += $value['benchMarkPremiumMain'] ?? 0;
            }
        }
        //商业险
        if ($biPremium > 0) {
            $this->printer->biPremiumPrinter = new PremiumBIPrinter();
            $this->printer->biPremiumPrinter->biPremium = $biPremium;
            $this->printer->biPremiumPrinter->biBasePremium = $biBasePremium;
            $biStartDate = $mainData['startDate'] ?? '';
            $this->printer->biPremiumPrinter->biStartData = mktime($mainData['startHour'] ?? '0', '0', '0', date('m', strtotime($biStartDate)), date('d', strtotime($biStartDate)), date('Y', strtotime($biStartDate)));
            $this->printer->biPremiumPrinter->biStartData = date('Y-m-d H:i:s', $this->printer->biPremiumPrinter->biStartData);
            $biEndDate = $mainData['endDate'] ?? '';
            $this->printer->biPremiumPrinter->biEndData = mktime($mainData['endHour'] ?? '0', '0', '0', date('m', strtotime($biEndDate)), date('d', strtotime($biEndDate)), date('Y', strtotime($biEndDate)));
            $this->printer->biPremiumPrinter->biEndData = date('Y-m-d H:i:s', $this->printer->biPremiumPrinter->biEndData);
            $this->printer->biPremiumPrinter->biDiscount = $mainData['discountMain'] ?? '';
            $this->printer->biInquiryNo = $mainData['proposalNo'] ?? '';
            $biFactor = $body['motorPlatDto'] ?? '';
            $this->printer->ncdFactor = $biFactor['claimAdjustReasonValue'] ?? '';

            //商业险系数
            $this->printer->premiumFactorPrinter->VCIFactorAppend('无赔优不浮动原因', 'noClaimAdjustReason', $biFactor['noClaimAdjustReason'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('无赔优调整系数', 'ncdRate', $biFactor['claimAdjustReasonValue'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('交通违法调整系数', 'peccancyAdjustReasonValue', $biFactor['peccancyAdjustReasonValue'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('交通违法浮动原因', 'peccancyAdjustReason', $biFactor['peccancyAdjustReason'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('交通违法不浮动原因', 'noPeccancyAdjustReason', $biFactor['noPeccancyAdjustReason'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('精准评分', 'score', $biFactor['score'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('业务评分', 'pointNumber', $biFactor['pointNumber'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('分值等级', 'pointGrade', $biFactor['pointGrade'] ?? '');
            $this->printer->premiumFactorPrinter->VCIFactorAppend('无赔优系数级别', 'claimAdjustLevel', $mainData['claimAdjustLevel'] ?? '');

            if ($biFactor['lastStartDate'] ?? '') {
                $this->printer->premiumFactorPrinter->VCIFactorAppend('上年商业险终保日期', 'lastBiEndData', $biFactor['lastStartDate']);
                $this->printer->premiumFactorPrinter->VCIFactorAppend('上年商业险起保日期', 'lastBiStartData', $biFactor['lastEndDate']);
            }
        }

        $this->printer->premiumFactorPrinter->ComFactorAppend('自主定价建议系数', 'autonomy', $mainData['autonomy'] ?? '');
        $this->printer->premiumFactorPrinter->ComFactorAppend('自主定价使用系数', 'autonomyValue', $mainData['autonomyValue'] ?? '');
        $this->printer->premiumFactorPrinter->ComFactorAppend('本次预估赔付率', 'lossedRate', $main['lossedRate'] ?? '');
        $this->printer->premiumFactorPrinter->ComFactorAppend('连续承保年数', 'insureYears', $main['insureYears'] ?? '');
        $this->printer->premiumFactorPrinter->ComFactorAppend('连续承保期间出险次数', 'claimTimes', $main['claimTimes'] ?? '');

        //续保类型
        $this->renewalFlag = $mainData['renewalFlag'] ?? '';

        //险种
        foreach ($riskArr as $kind) {
            if ($kind['kindCodeMain'] == 'BZ') {
                continue;
            }
            $coverage = new PremiumCoveragePrinter();
            $coverage->coverageCode = array_search($kind['kindCodeMain'] ?? '', LIHIEnums::$coverageCode);
            $coverage->coverageName = IDockEnums::$coverageCode[$coverage->coverageCode] ?? '';
            $coverage->premium = $kind['premiumMain'] ?? '';
            $coverage->basePremium = $kind['benchMarkPremiumMain'] ?? '';
            $coverage->amount = $kind['amountMain'] ?? '';
            $coverage->discount = $kind['discountMain'] ?? '';
            if (in_array($coverage->coverageCode, ['C08001', 'C08002', 'C08003', 'C08004', 'C18001', 'C18002', 'C18003', 'C18004'])) {
                $coverage->serviceTimes = $kind['quantityMain'] ?? '0';
            }
            $this->printer->coverageListAppend($coverage);
        }
        //特约
        $specialClause = $body['tprptEngageDTOList'] ?? [];
        foreach ($specialClause as $value) {
            $specialClauses = new SpecialClausesPrinter();
            $specialClauses->clauseCode = $value['clauseCode'] ?? '';
            $specialClauses->clauseName = $value['clausesName'] ?? '';
            $specialClauses->clauseContent = $value['clausesContext'] ?? '';
            if ($value['riskCode'] == '0502') {
                //商业险
                $specialClauses->riskType = 'VCI';
                $specialClauses->autoFlag = $value['mustFlag'] ? '0' : '1';
            } else {
                $specialClauses->riskType = 'TCI';
                $specialClauses->autoFlag = $value['mustFlag'] ? '0' : '1';
            }
            $this->printer->specialClausesAppend($specialClauses);
        }
        return $this;
    }

    /**
     * 重复投保
     * @param $body
     * @param $biStartDate
     * @param $ciStartDate
     * @param bool $hasPremium
     */
    private function repeat($body, $biStartDate, $ciStartDate, bool $hasPremium = false)
    {
        //交强过期日期
        $lastExpireDate = $body['mtplPlatDto']['lastExpireDate'] ?? '';

        $lastEndDate = $body['mtplPlatDto']['lastEndDate'] ?? '';

        $lastCiStartDate = max($lastExpireDate, $lastEndDate);

        if ($lastCiStartDate) {
            $lastCiStartDate = self::nextTime($lastCiStartDate);
        }

        //商业过期日期
        $lastExpireDate = $body['motorPlatDto']['lastExpireDate'] ?? '';

        $lastEndDate = $body['motorPlatDto']['lastEndDate'] ?? '';

        $lastBiStartDate = max($lastExpireDate, $lastEndDate);

        if ($lastBiStartDate) {
            $lastBiStartDate = self::nextTime($lastBiStartDate);
        }

        //脱保判定 和 提前报价
        if ($lastCiStartDate and $ciStartDate) {
            if (date('Y-m-d', strtotime($lastCiStartDate)) <= date('Y-m-d', strtotime($ciStartDate))) {
                $lastCiStartDate = '';
            }

            if (date('Y-m-d', strtotime($lastCiStartDate)) >= date('Y-m-d', strtotime('+31 day'))) {
                $lastCiStartDate = '';
            }
        }

        if ($lastBiStartDate and $biStartDate) {
            if (date('Y-m-d', strtotime($lastBiStartDate)) <= date('Y-m-d', strtotime($biStartDate))) {
                $lastBiStartDate = '';
            }

            if (date('Y-m-d', strtotime($lastBiStartDate)) >= date('Y-m-d', strtotime('+31 day'))) {
                $lastCiStartDate = '';
            }
        }

        if ($lastCiStartDate) {
            $lastCiStartDate = date('Y-m-d H:i:s', strtotime($lastCiStartDate));
            $this->printer->repeatInsurePrinter['ciStartData'] = $lastCiStartDate;
            $this->printer->repeatInsuredFlg = true;
        }

        if ($lastBiStartDate) {
            $lastBiStartDate = date('Y-m-d H:i:s', strtotime($lastBiStartDate));
            $this->printer->repeatInsurePrinter['biStartData'] = $lastBiStartDate;
            $this->printer->repeatInsuredFlg = true;
        }
    }

    /**
     * 重复投保
     * @param $body
     * @param $biStartDate
     * @param $ciStartDate
     * @return bool
     */
    private function repeat2($body, $biStartDate, $ciStartDate): bool
    {
        //交强过期日期
        $lastExpireDate = $body['mtplPlatDto']['lastExpireDate'] ?? '';

        $lastEndDate = $body['mtplPlatDto']['lastEndDate'] ?? '';

        $lastCiStartDate = max($lastExpireDate, $lastEndDate);

        if ($lastCiStartDate) {
            $lastCiStartDate = date('Y-') . date('m-d H:i:s', strtotime($lastCiStartDate));
        }

        //商业过期日期
        $lastExpireDate = $body['motorPlatDto']['lastExpireDate'] ?? '';

        $lastEndDate = $body['motorPlatDto']['lastEndDate'] ?? '';

        $lastBiStartDate = max($lastExpireDate, $lastEndDate);

        if ($lastBiStartDate) {
            $lastBiStartDate = date('Y-') . date('m-d H:i:s', strtotime($lastBiStartDate));
        }

        //脱保判定 和 提前报价
        if ($lastCiStartDate and $ciStartDate) {
            $lastCiDate = date('Y-m-d', strtotime($lastCiStartDate));
            if ($lastCiDate > date('Y-m-d', strtotime($ciStartDate)) and $lastCiDate < date('Y-m-d', strtotime('+31 day'))) {
                $lastCiStartDate = date('Y-m-d H:i:s', strtotime($lastCiStartDate));
                $this->printer->repeatInsurePrinter['ciStartData'] = $lastCiStartDate;
                $this->printer->repeatInsuredFlg = true;
            }
        }

        if ($lastBiStartDate and $biStartDate) {

            $lastBiDate = date('Y-m-d', strtotime($lastBiStartDate));

            if ($lastBiDate > date('Y-m-d', strtotime($biStartDate)) and $lastBiDate < date('Y-m-d', strtotime('+31 day'))) {
                $lastBiStartDate = date('Y-m-d H:i:s', strtotime($lastBiStartDate));
                $this->printer->repeatInsurePrinter['biStartData'] = $lastBiStartDate;
                $this->printer->repeatInsuredFlg = true;
            }
        }

        if ($this->printer->repeatInsuredFlg) {
            return true;
        }

        return false;
    }

    public function buildCoverage($isEnergy, array $orgList)
    {
        $orgList = array_combine(array_column($orgList, 'coverageCode'), $orgList);

        foreach ($this->printer->coverageList as $coverage) {
            /*** @var $coverage PremiumCoveragePrinter */

            if ($isEnergy) {
                $coverage->coverageCode = 'C1' . substr($coverage->coverageCode, 2, 4);
                $coverage->coverageName = IDockEnums::$coverageCode[$coverage->coverageCode];
            }

            if (!$coverage->amount) {
                $coverage->amount = $orgList[$coverage->coverageCode]->amount ?? '';
            }

            $coverage->quantity = $orgList[$coverage->coverageCode]->quantity ?? '';
            $coverage->unitAmount = $orgList[$coverage->coverageCode]->unitAmount ?? '';
            //服务次数回写
            $coverage->serviceTimes = $orgList[$coverage->coverageCode]->serviceTimes ?? '';
        }
    }

    private function setNonCarInfo($data)
    {
        $printer = new NonCarInquiryPrinter();
        $single = new NonCarInquirySinglePrinter();
        $single->productCode = $this->productCode;
        $single->planCode = $this->planCode;
        $single->inquiryNo = $data['subpolicyno'] ?? '';
        $printer->noCarInquirySingleAppend($single);
        $printer->totalPremium = $data['trialpremium'] ?? '0';
        $this->printer->nonCarInquiryPrinter = $printer;
    }

    /**
     * 续保标识
     * @param $licenseNo
     * @param $firstRegisterDate
     * @return void
     */
    public function renewalFlagType($licenseNo, $firstRegisterDate)
    {
        $renewalFlag = $this->renewalFlag;

        if (!strlen($renewalFlag)) {
            return;
        }
        //续保
        if ($renewalFlag == 1) {
            if ($this->printer->ciPremiumPrinter->ciPremium) {
                $this->printer->premiumFactorPrinter->ComFactorAppend('交强险忠诚度', 'CIRenewalType', '续');
            }
            if ($this->printer->biPremiumPrinter->biPremium) {
                $this->printer->premiumFactorPrinter->ComFactorAppend('商业险忠诚度', 'BIRenewalType', '续');
            }
        }

        //新保  转保
        if ($renewalFlag === '0') {
            $newCar = time() - strtotime($firstRegisterDate) < 60 * 60 * 24 * 30 * 3;
            if (!$licenseNo or $licenseNo == '新车' or $newCar) {
                if ($this->printer->ciPremiumPrinter->ciPremium) {
                    $this->printer->premiumFactorPrinter->ComFactorAppend('交强险忠诚度', 'CIRenewalType', '新');
                }
                if ($this->printer->biPremiumPrinter->biPremium) {
                    $this->printer->premiumFactorPrinter->ComFactorAppend('商业险忠诚度', 'BIRenewalType', '新');
                }
            } else {
                if ($this->printer->ciPremiumPrinter->ciPremium) {
                    $this->printer->premiumFactorPrinter->ComFactorAppend('交强险忠诚度', 'CIRenewalType', '转');
                }
                if ($this->printer->biPremiumPrinter->biPremium) {
                    $this->printer->premiumFactorPrinter->ComFactorAppend('商业险忠诚度', 'BIRenewalType', '转');
                }
            }
        }
    }

    /**
     * 返回询价车型
     * @param $modelList
     * @return bool
     */
    public function vehicleModelList($modelList): bool
    {
        if (!$modelList) {
            return false;
        }

        foreach ($modelList as $item) {
            $VehiclePrinter = new VehiclePrinter;

            $VehiclePrinter->vehicleModelCode = $item['modelCode'] ?? '';
            $VehiclePrinter->vehicleSeat = $item['limitLoadPerson'] ?? '';
            $VehiclePrinter->brandName = $item['brand'] ?? '';
            $VehiclePrinter->vehicleName = $item['carName'] ?? '';
            $VehiclePrinter->remark = $item['carName'] ?? '';
            $VehiclePrinter->vehicleExhaust = ($item['vehicleDisplacement'] ?? '') ? $item['vehicleDisplacement'] / 1000 : '';
            $VehiclePrinter->vehicleTonnage = $item['wholeWeight'] ?? '';
            $VehiclePrinter->power = $item['vehiclePower'] ?? '';
            $VehiclePrinter->vehiclePrice = $item['carValue'] ?? '';

            $VehiclePrinter->item = $item;

            $this->printer->vehicleModelAppend($VehiclePrinter);
        }

        if ($this->printer->vehicleModelList) {
            return true;
        }

        return false;
    }

    private static function nextTime($startTime,int $step = 0): string
    {
        if ($step) {
            $time = date('Y-',strtotime("+$step year")) . date('m-d H:i:s', strtotime($startTime));
        } else  {
            $time = date('Y-') . date('m-d H:i:s', strtotime($startTime));
        }

        if (strtotime($time) > time()) {
            return $time;
        } else {
            $step += 1;
            return self::nextTime($startTime,$step);
        }
    }
}
